/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package csse3004.GD;

import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Random;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 *
 * @author David Bullock 42062222
 */
public class createGraph {

    protected final Log logger = LogFactory.getLog(getClass());
    private String title = "";
    private LinkedHashMap<String, Integer> values = new LinkedHashMap<String, Integer>();
    private String errorMsg = "";
    /**
     * 0 for PieChart, 1 for Vertical Bar Chart and 2 for Horizontal Bar Graph
     * default is meant to be piechart
     */
    private int chartType = 0;
    private final int seed;

    /**
     * Creates a new Graph object
     * @param seed makes the div holding the graph unique by adding the seed to the end
     */
    public createGraph(int seed) {
        this.seed = seed;
    }

    /**
     *  Creates a new Graph object
     * @param seed makes the div holding the graph unique by adding the seed to the end
     * @param title
     * @param type the type of chart; accepts "pie","vertical" or "horizontal". Will ignore case.
     */
    public createGraph(int seed, String title, String type) {
        this.seed = seed;
        this.title = title;
        if (!this.setChartType(type))
            throw new UnsupportedOperationException("Invalid chart type");
    }
    
    /**
     * Returns the exact code that is needed by the googleGraph API to display the graph
     * @return the graph type name
     */
    public String getChartType() {
        switch (chartType) {
            case 0:
                return "PieChart";
            case 2:
                return "BarChart";
            case 1:
                return "ColumnChart";
            default:
                return "PieChart";
        }
    }

    /**
     * sets the chart type with a string. 
     * @param ChartType accepts "piechart","vertical" or "horizontal". Will ignore case.
     * @return If it was successful or not
     */
    public boolean setChartType(String ChartType) {
        ChartType = ChartType.toLowerCase();
        if (ChartType.equals("piechart")) {
            this.chartType = 0;
        } else if (ChartType.equals("pie")) {
            this.chartType = 0;
        } else if (ChartType.equals("vertical")) {
            this.chartType = 1;
        } else if (ChartType.equals("horizontal")) {
            this.chartType = 2;
        } else {
            return false;
        }
        return true;
    }
    
    public boolean setChartType(int chartType) {
        if (chartType<0 || chartType >3){
            logger.info("returning that there is an invalid input");
            return false;
        }
        this.chartType = chartType;
        return true;
    }

    public boolean isVisable() {
        return errorMsg.isEmpty();
    }

    public void setVisable(boolean Visable) {
        if (Visable){
            errorMsg = "The poll either doesn't exist or isn't set to allow viewing";
        } else
            errorMsg = "";
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public LinkedHashMap<String, Integer> getValues() {
        return values;
    }

    public void setValues(LinkedHashMap<String, Integer> values) {
        this.values = values;
    }

    public void addValue(String label, int value) {
        values.put(label, value);
    }

    /**
     * will convert the bean into the exact HTML code needed to display it.
     * Ensure that this is printed without the c:out tag, as that automatically 
     * escapes the HTML tags
     * @return 
     */
    public String display(int hight, int width) {
        String html = "<!--See the controller's bean to modify the creation of this chart-->\n";
        if (isVisable() == false) {
            html += "</br></br><p>"+errorMsg+"</p></br></br>\n";
        } else {
            html += "<script type=\"text/javascript\" src=\"https://www.google.com/jsapi\"></script>\n";
            html += "<script type=\"text/javascript\">\n";
            // Load the Visualization API and the piechart package.
            html += "google.load('visualization', '1.0', {'packages':['corechart']});\n";
            // Set a callback to run when the Google Visualization API is loaded.
            html += "google.setOnLoadCallback(drawChart);\n";
            // Callback that creates and populates a data table, 
            // instantiates the pie chart, passes in the data and
            // draws it.
            html += "function drawChart() {\n";

            // Create the data table.
            html += "var data = new google.visualization.DataTable();\n";
            html += "data.addColumn('string', 'Question');\n";
            html += "data.addColumn('number', 'Result');\n";
            Set<String> label = this.getValues().keySet();
            Collection<Integer> value = this.getValues().values();
            Iterator lblItr = label.iterator();
            Iterator valItr = value.iterator();
            while (lblItr.hasNext()) {
                html += "data.addRow(['" + lblItr.next() + "'," + valItr.next() + "]);\n";
            }

            // Set chart options
            html += "var options = {'title':'" + title + "','width':" + width + ",'height':" + hight + "};\n";

            // Instantiate and draw our chart, passing in some options.
            html += "var chart = new google.visualization." + this.getChartType();
            html += "(document.getElementById('chart_div"+seed+"'));\n";
            html += "chart.draw(data, options);\n";
            html += "}\n";
            html += "</script>\n";

            html += "<!--Div that will hold the pie chart-->\n";
            html += "<div id=\"chart_div"+seed+"\"></div>\n";
        }

        return html;
    }

    /**
     * creates a fake poll result that has a random chart type, and will be 
     * invisible if an even qid is passed in
     * @param qid the question ID, determines if the results are visible
     * @return 
     */
    public createGraph genData(int qid) {
        createGraph bean = new createGraph(1);
        if (qid % 2 == 0) {//already set to false, just return
            return bean;
        }
        logger.info("should have values");
        bean.setVisable(true);
        bean.addValue("Male", 211);
        bean.addValue("female", 223);
        bean.addValue("Other", 2);
        bean.addValue("Did not respond", 17);
        int type = new Random().nextInt(3);
        logger.info(type);
        bean.setChartType(type);
        return bean;
    }
}
